package com.example.demo.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

/**
 * 版权工具类，提供版权相关的辅助方法
 * @author Atanycosts
 * @date 2025/3/19
 */
@Slf4j
@Component
public class CopyrightUtils {

    // 静态上传目录，默认值为相对路径"uploads"
    private static String UPLOAD_DIR = "uploads";
    
    // 单例实例，用于Spring初始化
    private static CopyrightUtils instance;
    
    @Value("${copyright.upload.dir:uploads}")
    private String configuredUploadDir;
    
    @PostConstruct
    public void init() {
        UPLOAD_DIR = configuredUploadDir;
        instance = this;
        log.info("上传目录已设置为: {}", UPLOAD_DIR);
        initUploadDirectory();
    }
    
    /**
     * 计算图片文件的哈希值
     * @param imageFile 图片文件
     * @return 图片的哈希值（十六进制字符串）
     */
    public static String calculateImageHash(MultipartFile imageFile) {
        if (imageFile == null || imageFile.isEmpty()) {
            log.error("图片文件为空");
            return null;
        }
        
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(imageFile.getBytes());
            return bytesToHex(hash);
        } catch (NoSuchAlgorithmException | IOException e) {
            log.error("计算图片哈希异常: {}", e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 计算文件的哈希值
     * @param file 文件
     * @return 文件的哈希值（十六进制字符串）
     */
    public static String calculateFileHash(File file) {
        if (file == null || !file.exists() || !file.isFile()) {
            log.error("文件不存在或不是文件");
            return null;
        }
        
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] fileBytes = Files.readAllBytes(file.toPath());
            byte[] hash = digest.digest(fileBytes);
            return bytesToHex(hash);
        } catch (NoSuchAlgorithmException | IOException e) {
            log.error("计算文件哈希异常: {}", e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 保存图片文件
     * @param imageFile 图片文件
     * @param uploadDir 上传目录
     * @return 保存后的文件路径
     * @throws IOException 保存异常
     */
    public static String saveImageFile(MultipartFile imageFile, String uploadDir) throws IOException {
        if (imageFile == null || imageFile.isEmpty()) {
            throw new IllegalArgumentException("图片文件为空");
        }
        
        // 确保目录存在
        makeUploadDirExists(uploadDir);
        
        // 获取原始文件名和扩展名
        String originalFilename = imageFile.getOriginalFilename();
        String extension = "";
        if (originalFilename != null && originalFilename.contains(".")) {
            extension = originalFilename.substring(originalFilename.lastIndexOf("."));
        }
        
        // 生成唯一文件名
        String fileName = UUID.randomUUID().toString() + extension;
        String filePath = uploadDir + File.separator + fileName;
        
        // 保存文件
        File dest = new File(filePath);
        imageFile.transferTo(dest);
        
        log.info("图片文件已保存到: {}", filePath);
        return filePath;
    }
    
    /**
     * 确保上传目录存在
     * @param dirPath 目录路径
     * @throws IOException 如果无法创建目录
     */
    public static void makeUploadDirExists(String dirPath) throws IOException {
        File directory = new File(dirPath);
        if (!directory.exists()) {
            log.info("创建目录: {}", dirPath);
            if (!directory.mkdirs()) {
                log.error("无法创建目录: {}", dirPath);
                throw new IOException("无法创建目录: " + dirPath);
            }
        }
    }
    
    /**
     * 获取上传目录
     * @param address 用户地址
     * @param copyrightId 版权ID
     * @return 上传目录
     */
    public static String getUploadDirectory(String address, String copyrightId) {
        // 基本的上传目录
        String baseDir = UPLOAD_DIR;
        
        // 如果地址不为空，添加用户地址子目录
        if (address != null && !address.isEmpty()) {
            // 截取地址的一部分作为子目录名
            String addressDir = address.substring(0, Math.min(10, address.length()));
            baseDir = baseDir + File.separator + addressDir;
        }
        
        // 如果版权ID不为空，添加版权ID子目录
        if (copyrightId != null && !copyrightId.isEmpty()) {
            baseDir = baseDir + File.separator + copyrightId;
        }
        
        return baseDir;
    }
    
    /**
     * 将字节数组转换为十六进制字符串
     * @param bytes 字节数组
     * @return 十六进制字符串
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }
    
    /**
     * 验证版权ID是否有效
     * @param copyrightId 版权ID
     * @return 是否有效
     */
    public static boolean isValidCopyrightId(BigInteger copyrightId) {
        return copyrightId != null && copyrightId.compareTo(BigInteger.ZERO) > 0;
    }
    
    /**
     * 从合约返回的哈希值中解析出图片哈希
     * @param contractHash 合约返回的哈希值
     * @return 图片哈希
     */
    public static String parseImageHashFromContract(String contractHash) {
        if (contractHash == null || contractHash.isEmpty()) {
            return null;
        }
        
        // 清理字符串并返回
        return contractHash.replaceAll("\"", "").trim();
    }
    
    /**
     * 解析数组数据
     * @param arrayData 数组数据字符串
     * @return 解析后的字符串数组
     */
    public static String[] parseArrayData(String arrayData) {
        if (arrayData == null || arrayData.isEmpty()) {
            return new String[0];
        }
        
        // 清理输入
        String cleanInput = arrayData.trim();
        
        // 如果包含方括号，去除它们
        if (cleanInput.startsWith("[") && cleanInput.endsWith("]")) {
            cleanInput = cleanInput.substring(1, cleanInput.length() - 1);
        }
        
        // 按逗号分割（但保留引号内的逗号）
        String[] parts = cleanInput.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
        
        // 清理每个部分
        for (int i = 0; i < parts.length; i++) {
            parts[i] = parts[i].replaceAll("\"", "").trim();
        }
        
        return parts;
    }
    
    /**
     * 初始化上传目录
     * @return 上传根目录
     */
    public static String initUploadDirectory() {
        try {
            // 创建上传根目录
            Path uploadPath = Paths.get(UPLOAD_DIR);
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
                log.info("创建上传根目录: {}", uploadPath.toAbsolutePath());
            }
            return uploadPath.toAbsolutePath().toString();
        } catch (IOException e) {
            log.error("初始化上传目录异常: {}", e.getMessage(), e);
            throw new RuntimeException("无法初始化上传目录: " + e.getMessage(), e);
        }
    }
}
